package it.koutifaris.travianmap.ui;

import it.koutifaris.travianmap.R;
import it.koutifaris.travianmap.context.ContextRetreiver;
import it.koutifaris.travianmap.dal.MapService;
import it.koutifaris.travianmap.dal.MapServiceFactory;
import it.koutifaris.travianmap.dal.RevisionService;
import it.koutifaris.travianmap.dal.TravianServerService;
import it.koutifaris.travianmap.dal.TravianServerService.TravianServer;
import it.koutifaris.travianmap.map.WorldMap;
import it.koutifaris.travianmap.map.randommap.RandomWorldMap;
import it.koutifaris.travianmap.ui.WorldMapViewInizializer.StepFinal;
import it.koutifaris.travianmap.ui.WorldMapViewInizializer.StepInitialState;
import it.koutifaris.travianmap.ui.viewstate.DynamicViewState;
import it.koutifaris.travianmap.ui.viewstate.ViewStatePersister;
import it.koutifaris.travianmap.ui.viewstate.ViewStateSource;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;

public class MapActivity extends FragmentActivity {

	public static final String TRAVIAN_SERVER_PARAM = "TRAVIAN_SERVER";

	private static final String VIEW_STATE_PARAM = "VIEW_STATE";

	private MapService mapService;
	private ViewStateSource viewStateSource;
	private ViewStatePersister statePersister;

	private static RandomWorldMap randomWorldMap;

	public static void startActivity(Activity currentActivity, TravianServerService.TravianServer travianServer) {
		Intent intent = new Intent(currentActivity, MapActivity.class);
		intent.putExtra(MapActivity.TRAVIAN_SERVER_PARAM, travianServer);
		currentActivity.startActivity(intent);
	}

	public static void startActivityWithRandomMap(Activity currentActivity) {
		randomWorldMap = new RandomWorldMap(WorldMap.TRAVIAN_MAP_RADIUS);

		Intent intent = new Intent(currentActivity, MapActivity.class);
		currentActivity.startActivity(intent);
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		ContextRetreiver.contextRetreiver().setCurrentContext(this);

		TravianServerService.TravianServer travianServer = getTravianServer();
		statePersister = new ViewStatePersister(travianServer);

		WorldMap worldMap;
		if (travianServer != null) {
			ContextRetreiver.contextRetreiver().setCurrentServerId(travianServer.getServerId());
			worldMap = loadMapFromServer(travianServer);
		} else {
			worldMap = randomWorldMap;
		}

		this.setContentView(R.layout.map);

		viewStateSource = initWorldMapView(worldMap, getPreviousState(savedInstanceState));
	}

	@Override
	protected void onStart() {
		super.onStart();
		ContextRetreiver.contextRetreiver().setCurrentContext(this);
	}

	private TravianServer getTravianServer() {
		TravianServer result = null;

		if (getIntent().getExtras() != null) {
			result = getIntent().getExtras().getParcelable(TRAVIAN_SERVER_PARAM);
		}

		return result;
	}

	private WorldMap loadMapFromServer(TravianServerService.TravianServer travianServer) {
		MapServiceFactory mapServiceFactory = ContextRetreiver.contextRetreiver()
				.getCurrentContext().getMapServiceFactory(travianServer.getServerId());

		mapService = mapServiceFactory.mapService();
		RevisionService revisionService = mapServiceFactory.revisionService();

		WorldMap worldMap = mapService.loadMap(revisionService.getLatestRevision());
		revisionService.close();

		return worldMap;
	}

	private DynamicViewState getPreviousState(Bundle savedInstanceState) {
		DynamicViewState result = null;

		if (savedInstanceState != null) {
			result = savedInstanceState.getParcelable(VIEW_STATE_PARAM);
		} else if (getTravianServer() != null) {
			result = statePersister.loadViewStateFromDB();
		}

		return result;
	}

	private ViewStateSource initWorldMapView(WorldMap worldMap, DynamicViewState previousState) {
		WorldMapView worldMapView = (WorldMapView) this.findViewById(R.id.worldMapView);
		StepInitialState stepInitialState = worldMapView.initializer()
				.startInitialing()
				.withMap(worldMap)
				.withDefaultTheme();

		StepFinal finalStep;
		if (previousState != null) {
			finalStep = stepInitialState.withInitialState(previousState);
		} else {
			finalStep = stepInitialState.withDefaultInitialState();
		}

		return finalStep.done().getViewStateSource();
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		outState.putParcelable(VIEW_STATE_PARAM, viewStateSource.getViewState());
		super.onSaveInstanceState(outState);
	}

	@Override
	protected void onPause() {
		super.onPause();
		statePersister.saveViewState(viewStateSource.getViewState());
	}

	@Override
	protected void onDestroy() {
		if (mapService != null) {
			mapService.close();
		}

		super.onDestroy();
	}

}
